package com.yanqu.road.dao.impl.channelcenter;

import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.impl.TempDao;
import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 跨地区活动
 */
public class ChannelActivityDaoImpl extends TempDao {

    // ========================= activityInfo ==============================

    /**
     * 活动信息
     */
    public Map<Integer, ActivityInfo> getAllActivityInfoMap(long serverId, int channelActivityTimeZone) {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Integer, ActivityInfo> dataMap = new ConcurrentHashMap<>();
        String sql = "select * from t_n_activity_main where serverList like ?";
        try {
            getDb().setConnName(DbNameStrategy.getChannelCenterDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setString(i++, "%" + serverId + "%");
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityInfo data = initActivityInfo(rs, channelActivityTimeZone);
                dataMap.put(data.getActivityId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    /**
     * 活动信息
     */
    public Map<Integer, ActivityInfo> getAllActivityInfoMap(int channelActivityTimeZone) {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Integer, ActivityInfo> dataMap = new ConcurrentHashMap<>();
        String sql = "select * from t_n_activity_main";
        try {
            getDb().setConnName(DbNameStrategy.getChannelCenterDb());
            call = getDb().getConnection().prepareCall(sql);
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityInfo data = initActivityInfo(rs, channelActivityTimeZone);
                dataMap.put(data.getActivityId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    private ActivityInfo initActivityInfo(ResultSet rs, int channelActivityTimeZone) throws SQLException {
        ActivityInfo data = new ActivityInfo();
        data.setActivityId(rs.getInt("activityId"));
        data.setActivityName(rs.getString("activityName"));
        data.setActivityDesc(rs.getString("activityDesc"));
        data.setType(rs.getInt("type"));
        data.setChildType(rs.getInt("childType"));
        data.setBeginShowTime(rs.getTimestamp("beginShowTime").getTime() / 1000);
        data.setEndShowTime(rs.getTimestamp("endShowTime").getTime() / 1000);
        data.setBeginTime(rs.getTimestamp("beginTime").getTime() / 1000);
        data.setEndTime(rs.getTimestamp("endTime").getTime() / 1000);
        data.setIcon(rs.getString("icon"));
        data.setOrder(rs.getInt("order"));
        data.setParam1(rs.getString("param1"));
        data.setParam2(rs.getString("param2"));
        data.setParam3(rs.getString("param3"));
        data.setParam4(rs.getString("param4"));
        data.setParam5(rs.getString("param5"));
        data.setParam6(rs.getString("param6"));
        data.setUnionGroup(rs.getString("unionGroup"));
        data.setServerListStr(rs.getString("serverList"));
        data.setServerIdList(StringUtils.stringToLongList(data.getServerListStr(), ","));
        data.setServerListStr2(rs.getString("serverList2"));
        data.setCrossId(rs.getLong("crossServerId"));

        // 转化时区
        data.timeZoneChange(channelActivityTimeZone);

        return data;
    }

    /**
     * 根据活动ID获取活动信息
     */
    public ActivityInfo getActivityInfoById(int activityId, int channelActivityTimeZone) {
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_n_activity_main where activityId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getChannelCenterDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++, activityId);
            rs = call.executeQuery();
            if (rs.next()) {
                ActivityInfo info = initActivityInfo(rs, channelActivityTimeZone);
                return info;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return null;
    }

    public Map<Integer, ActivityInfo> getActivityInfoByType(List<Integer> activityTypeList,String nowTimeStr, int channelActivityTimeZone) {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Integer, ActivityInfo> dataMap = new ConcurrentHashMap<>();
        if(null == activityTypeList || activityTypeList.size() <= 0){
            return dataMap;
        }
        String activityTypeCondition = "type in(" + StringUtils.listToString(activityTypeList, ",") + ")";
        String sql = "select * from t_n_activity_main where " + activityTypeCondition + " and endShowTime>? and beginShowTime<=? ";
        try {
            getDb().setConnName(DbNameStrategy.getChannelCenterDb());
            call = getDb().getConnection().prepareCall(sql);
            call.setString(1, nowTimeStr);
            call.setString(2, nowTimeStr);
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityInfo info = initActivityInfo(rs, channelActivityTimeZone);
                dataMap.put(info.getActivityId(), info);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    // ========================= condition ==============================

    /**
     * 活动condition
     */
    public List<ActivityConditionInfo> getActivityConditionInfoList(int activityId, int conditionType) {
        List<ActivityConditionInfo> infoList = new ArrayList<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_n_activity_condition where activityId=? and `type`=?";
        try {
            getDb().setConnName(DbNameStrategy.getChannelCenterDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++, activityId);
            call.setInt(i++, conditionType);
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityConditionInfo data = initActivityConditionInfo(rs);
                infoList.add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return infoList;
    }

    /**
     * 活动condition
     */
    public Map<Integer, List<ActivityConditionInfo>> getActivityConditionInfoMap(List<Integer> activityIdList) {
        if (activityIdList == null || activityIdList.size() <= 0) {
            return new ConcurrentHashMap<>();
        }
        Map<Integer, List<ActivityConditionInfo>> infoMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_n_activity_condition where activityId in(" + StringUtils.listToString(activityIdList, ",") + ")";
        try {
            getDb().setConnName(DbNameStrategy.getChannelCenterDb());
            call = getDb().getConnection().prepareCall(sql);
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityConditionInfo data = initActivityConditionInfo(rs);
                if (!infoMap.containsKey(data.getActivityId())) {
                    infoMap.put(data.getActivityId(), new ArrayList<>());
                }
                infoMap.get(data.getActivityId()).add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return infoMap;
    }

    private ActivityConditionInfo initActivityConditionInfo(ResultSet rs) throws SQLException {
        ActivityConditionInfo data = new ActivityConditionInfo();
        data.setConditionId(rs.getInt("id"));
        data.setActivityId(rs.getInt("activityId"));
        data.setTitle(rs.getString("title"));
        data.setDesc(rs.getString("desc"));
        data.setType(rs.getInt("type"));
        data.setRewardStr(rs.getString("rewards"));
        data.setParamStr(rs.getString("params"));
        data.setReward(PropertyHelper.parseStringToProperty(data.getRewardStr()));
        data.setParamList(StringUtils.stringToBigIntegerList(data.getParamStr(), "\\|"));
        String value = rs.getString("extendParam");
        if (!StringUtils.isNullOrEmpty(value)) {
            data.setExtendParam(value);
        }
        //职位奖励 会长奖励|副会长奖励|精英奖励
        data.setPositionRewardStr(rs.getString("masterRewards"));
        List<String> positionStrList = StringUtils.stringToStringList(data.getPositionRewardStr(), "\\|");
        if (positionStrList.size() > 0 && !StringUtils.isNullOrEmpty(positionStrList.get(0))) {
            data.setMasterReward(PropertyHelper.parseStringToProperty(positionStrList.get(0)));
            data.setMasterRewardStr(positionStrList.get(0));
        }
        if (positionStrList.size() > 1 && !StringUtils.isNullOrEmpty(positionStrList.get(1))) {
            data.setDeputyMasterRewardStr(positionStrList.get(1));
        }
        if (positionStrList.size() > 2 && !StringUtils.isNullOrEmpty(positionStrList.get(2))) {
            data.setEliteRewardStr(positionStrList.get(2));
        }
        data.setActtype(rs.getString("acttype"));
        return data;
    }

    // ========================= config ==============================

    /**
     * 活动通用配置
     */
    public Map<Integer, Map<String, ActivityConfig>> getActivityConfigMap(List<Integer> activityIdList) {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Integer, Map<String, ActivityConfig>> dataMap = new ConcurrentHashMap<>();
        if (null == activityIdList || activityIdList.size() <= 0) {
            return dataMap;
        }
        String sql = "select * from t_n_activity_config where activityId in(" + StringUtils.listToString(activityIdList, ",") + ")";
        try {
            getDb().setConnName(DbNameStrategy.getChannelCenterDb());
            call = getDb().getConnection().prepareCall(sql);
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityConfig config = new ActivityConfig();
                config.setActivityId(rs.getInt("activityId"));
                config.setId(rs.getInt("id"));
                config.setParam(rs.getString("param"));
                config.setValue(rs.getString("value"));
                if (!dataMap.containsKey(config.getActivityId())) {
                    dataMap.put(config.getActivityId(), new ConcurrentHashMap<>());
                }
                dataMap.get(config.getActivityId()).put(config.getParam(), config);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    // ========================= 特殊SQL ==============================

    public ActivityInfo getOpenWasheActivityInfo(int channelId, int channelActivityTimeZone) {
        Timestamp now = new Timestamp(System.currentTimeMillis());
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_n_activity_main where " +
                "beginShowTime<=? and ?<=endShowTime " +
                "and type=? " +
                "and param6 like ? ";
        try {
            getDb().setConnName(DbNameStrategy.getChannelCenterDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setTimestamp(i++, now);
            call.setTimestamp(i++, now);
            call.setInt(i++, eActivityType.WasheActivity.getValue());
            call.setString(i++, "%" + channelId + "%");
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityInfo data = initActivityInfo(rs, channelActivityTimeZone);
                List<Integer> list = StringUtils.stringToIntegerList(data.getParam6(), ";");
                boolean anyMatch = list.stream().anyMatch(item -> item == channelId);
                if (anyMatch) {
                    return data;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return null;
    }

    public List<ActivityInfo> getAllOpenWasheActivityInfo(int channelActivityTimeZone) {
        List<ActivityInfo> list = new ArrayList<>();
        Timestamp now = new Timestamp(System.currentTimeMillis());
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_n_activity_main where " +
                "beginShowTime<=? and ?<=endShowTime " +
                "and type=? ";
        try {
            getDb().setConnName(DbNameStrategy.getChannelCenterDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setTimestamp(i++, now);
            call.setTimestamp(i++, now);
            call.setInt(i++, eActivityType.WasheActivity.getValue());
            rs = call.executeQuery();
            while (rs.next()) {
                ActivityInfo data = initActivityInfo(rs, channelActivityTimeZone);
                list.add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return list;
    }

}
